home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 2000 #4 / Amiga Plus CD - 2000 - No. 4.iso / PowerPC / Dev / PPCRelease / Tools / PPCDebug.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-24  |  58.1 KB  |  1,874 lines

  1. /***************************************************************************
  2.  *
  3.  *                       PPCDebug
  4.  *
  5.  *  PPCDebug is free software; you can redistribute it and/or modify
  6.  *  it under the terms of the GNU General Public License as published by
  7.  *  the Free Software Foundation; either version 2, or (at your option)
  8.  *  any later version.
  9.  *
  10.  *
  11.  *  This started as a small example to show how to
  12.  *  use the ppc.library`s trap function and grew into
  13.  *  a small, not very polished but useful, PPC debugger.
  14.  *
  15.  *  I`m sure you would like to see more features and because
  16.  *  the source is public it should be easy to add the needed
  17.  *  functions personally.
  18.  *  But to coordinate this I suggest to contact me if these
  19.  *  features should be available to everybody.
  20.  *
  21.  *  Ralph Schmidt
  22.  *
  23.  *
  24.  *
  25.  ***************************************************************************/
  26.  
  27. #include <exec/types.h>
  28. #include <exec/nodes.h>
  29. #include <exec/lists.h>
  30. #include <exec/libraries.h>
  31. #include <exec/memory.h>
  32. #include <exec/alerts.h>
  33. #include <exec/interrupts.h>
  34. #include <clib/alib_stdio_protos.h>
  35. #include <dos/dos.h>
  36. #include <dos/dosextens.h>
  37. #include <dos/dostags.h>
  38. #include <proto/exec.h>
  39. #include <proto/dos.h>
  40. #include <PowerUP/PPCLib/Interface.h>
  41. #include <PowerUP/PPCLib/tasks.h>
  42. #include <PowerUP/PPCLib/ppc.h>
  43. #include <PowerUP/PPCLib/object.h>
  44. #include <PowerUP/PPCDisslib/PPCDiss.h>
  45. #include <PowerUP/pragmas/ppc_pragmas.h>
  46. #include <PowerUP/clib/ppc_protos.h>
  47. #include <PowerUP/pragmas/ppcdiss_pragmas.h>
  48. #include <PowerUP/clib/ppcdiss_protos.h>
  49. #include <ctype.h>
  50. #include <string.h>
  51. #include <stdlib.h>
  52. #include "PPCDebug_VERSION.h"
  53. #include "/ArgParser/ArgParser.h"
  54. #include "/ArgParser/ArgParser_protos.h"
  55.  
  56. void __builtin_emit(int);
  57.  
  58. struct    BreakPoint
  59. {
  60.     struct Node    Node;
  61.     ULONG        *Address;
  62.     ULONG        Opcode;
  63. };
  64.  
  65. #define    EMPTYTRACEPOINT    ((ULONG*)0xffffffff)
  66.  
  67. #define    LINEMAX        256
  68.  
  69.  
  70. /* Quick Signal hack because i'm too lazy
  71.  * to use AllocSignal()
  72.  */
  73.  
  74. #define    SIGNAL_EXCEPTION    31
  75.  
  76.  
  77. #define    MSRF_FP        0x2000
  78.  
  79.  
  80. #define    OPCODE_LR    0x1
  81. #define    OPCODE_TD31_0_0    0x7fe00008
  82.  
  83. #define    MASK_21_30(x)    (x &((1<<(31-21))|(1<<(31-22))|(1<<(31-23))|(1<<(31-24))|(1<<(31-25))|(1<<(31-26))|(1<<(31-27))|(1<<(31-28))|(1<<(31-29))|(1<<(31-30))))
  84. #define    OP_ID(a,b,c,d,e,f,g,h,i,j)  ((1<<10)*a | \
  85.                                       (1<<9)*b | \
  86.                                       (1<<8)*c | \
  87.                                       (1<<7)*d | \
  88.                                       (1<<6)*e | \
  89.                                       (1<<5)*f | \
  90.                                       (1<<4)*g | \
  91.                                       (1<<3)*h | \
  92.                                       (1<<2)*i | \
  93.                                       (1<<1)*j)
  94.  
  95.  
  96. #define    SHOWREG_GPR    0x1
  97. #define    SHOWREG_FRAME    0x2
  98. #define    SHOWREG_FPUHEX    0x4
  99. #define    SHOWREG_FPU    0x8
  100. #define    SHOWREG_MMU    0x10
  101. #define    SHOWREG_MISC    0x20
  102.  
  103. extern struct ExecBase        *SysBase;
  104. extern struct Library        *DosBase;
  105. struct Library        *PPCLibBase;
  106. struct Library        *PPCDissBase;
  107. struct Hook        MyHook;
  108. struct Hook        MyAddressHook;
  109. struct Hook        MySymbolHook;
  110. struct Hook        MyRelocHook;
  111. struct Hook        MyScanSymbolHook;
  112. struct Hook        MyArgParserSymbolHook;
  113. struct Hook        MyGetDataHook;
  114. struct Process        *MsgProcess;
  115. struct ExceptionMsg    ExceptionMsg;
  116. void            *ExceptionTask;
  117. BPTR            InputFile;
  118. BPTR            OutputFile;
  119. ULONG            CPU;
  120. ULONG            PC;
  121. ULONG            NewPC;
  122. ULONG            MEM;
  123. struct PPCObjectInfo    MyInfo;
  124. void            *MyObject;
  125. BOOL            MyInfoStatus;
  126. extern ULONG        __base;
  127. struct List        BreakPointList;
  128. struct BreakPoint    MyTracePoint;
  129. BOOL            GoSimulateFlag;
  130. ULONG            ShowRegFormat=(SHOWREG_GPR | SHOWREG_FRAME | SHOWREG_FPU);
  131.  
  132.  
  133.  
  134. UBYTE    vers[] = VERSTAG;
  135.  
  136. char    *ExceptionStringTable[]=
  137. {
  138.     "Unknown",
  139.     "Reset",
  140.     "Machine Check",
  141.     "Data Access",
  142.     "Instruction Access",
  143.     "External Interrupt",
  144.     "Alignment",
  145.     "Program",
  146.     "FPU Unavailable",
  147.     "Decrementer",
  148.     "Interface Error",
  149.     "Reserved B",
  150.     "System Call",
  151.     "Trace",
  152.     "FPU Assist",
  153.     "Reserved F",
  154.     "Instruction Translation Miss",
  155.     "Data Load Translation Miss",
  156.     "Data Store Translation Miss",
  157.     "Instruction Address Point",
  158.     "System Management Interrupt"
  159. };
  160.  
  161.  
  162. //#define isspace(c)      ((c == ' ')||(c == '\t') || (c == '\n'))
  163. #define QUOTE       '"'
  164. #define ESCAPE '*'
  165. #define ESC '\x1b'
  166. #define NL '\n'
  167.  
  168. #define MSGID_EXIT        0x44584954
  169. #define    DEFAULTPPCSTACK        0x10000
  170.  
  171. /* VBCC compatibility
  172.  * extension
  173.  * The CTRL-D feature of the
  174.  * runppc should be put into
  175.  * PPCTool as i think it`s too
  176.  * dangerous for normal usage.
  177.  * The signal handling in the old
  178.  * runppc was also not 100% as
  179.  * some shell(s) set the last
  180.  * DosPacket`s Task as the receiver
  181.  * of the signal.
  182.  * Don`t remember now if it was
  183.  * WShell or Shell.
  184.  * With the PPCTASKTAG_BREAKSIGNAL
  185.  * parameter the ppclib waits on
  186.  * both tasks.
  187.  * The creator task and the PPC 68k
  188.  * msg task.
  189.  */
  190.  
  191. struct StartupData
  192. {
  193.     void    *M68kPort;    /* the PowerPC task can send messages to this port */
  194.     BPTR    std_in;        /* standard input handle */
  195.     BPTR    std_out;    /* standard output handle */
  196.     BPTR    std_err;    /* standard error handle */
  197.     LONG    ReturnCode;    /* here we will find the return code from the PPC task */
  198.     ULONG    Flags;        /* additional flags (currently unused) */
  199. };
  200.  
  201. #define STARTUPF_ELFLOADSEG    0x1
  202.  
  203. /*------------------------------------------------------------------------*/
  204. /*------------------------------------------------------------------------*/
  205. /*------------------------------------------------------------------------*/
  206. /*------------------------------------------------------------------------*/
  207. /*------------------------------------------------------------------------*/
  208. /*------------------------------------------------------------------------*/
  209. /*------------------------------------------------------------------------*/
  210. /*------------------------------------------------------------------------*/
  211.  
  212. BOOL    GetValue(char    *Ptr,
  213.                  ULONG    *Result)
  214. {
  215. struct TagItem    MyTags[5];
  216. ULONG        Error;
  217. ULONG        Type;
  218. void        *MyParseHandle;
  219.  
  220.   Type            =    PARSETYPE_INTEGER;
  221.  
  222.   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  223.   MyTags[0].ti_Data    =    (ULONG) &Error;
  224.   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  225.   MyTags[1].ti_Data    =    (ULONG) Result;
  226.   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  227.   MyTags[2].ti_Data    =    (ULONG) &Type;
  228.   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  229.   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  230.   MyTags[4].ti_Tag    =    TAG_END;
  231.  
  232.   if (MyParseHandle=CreateParseHandle(MyTags))
  233.   {
  234.     MyTags[0].ti_Tag    =    TAG_END;
  235.     if (ParseArgument(MyParseHandle,
  236.                       Ptr,
  237.                       MyTags))
  238.     {
  239.       return(TRUE);
  240.     }
  241.     else
  242.     {
  243.       printf("Error 0x%08lx\n",Error);
  244.     }
  245.   }
  246.   else
  247.   {
  248.     printf("Not enough memory\n");
  249.   }
  250.   return(FALSE);
  251. }
  252.  
  253.  
  254. /*------------------------------------------------------------------------*/
  255. /*------------------------------------------------------------------------*/
  256. /*------------------------------------------------------------------------*/
  257. /*------------------------------------------------------------------------*/
  258. /*------------------------------------------------------------------------*/
  259. /*------------------------------------------------------------------------*/
  260. /*------------------------------------------------------------------------*/
  261. /*------------------------------------------------------------------------*/
  262.  
  263. BOOL    ShowDiss(ULONG    Address,
  264.                  ULONG    Lines,
  265.                  BOOL    ShowData)
  266. {
  267. void        *PPCDissHandle;
  268. int        i;
  269. char        LineBuffer[128];
  270. struct TagItem    MyTags[1];
  271.  
  272. //  __builtin_emit(0x4afc);
  273.  
  274.   MyTags[0].ti_Tag    =    TAG_END;
  275.  
  276. //  Printf("PC: 0x%08lx::\n",Address);
  277.  
  278.   if (PPCDissHandle = CreateDisAssHandleTags(DISASS_DEFINEPC,Address,
  279.                                              DISASS_SHOWDATA,ShowData,
  280.                                              DISASS_USEDC68KDESC, TRUE,
  281.                                              DISASS_ADDRESSHOOK,&MyAddressHook,
  282.                                              DISASS_SYMBOLHOOK,&MySymbolHook,
  283.                                              DISASS_RELOCHOOK,&MyRelocHook,
  284.                                              DISASS_GETDATAHOOK,&MyGetDataHook,
  285.                                              TAG_DONE))
  286.   {
  287.     for(i=0;i<Lines;i++)
  288.     {
  289.       if (MyInfoStatus==FALSE ||
  290.           (MyInfo.Address==0 && MyInfo.Size==0) ||
  291.           (MyInfo.Type==PPCELFINFOTYPE_SECTION) ||
  292.           (Address < MyInfo.Address || Address >= (MyInfo.Address+MyInfo.Size)))
  293.       {
  294. //    __builtin_emit(0x4afc);
  295.         MyInfo.Name        =    NULL;
  296.         MyInfo.Address        =    Address;
  297.         MyInfo.Size        =    0;
  298.         MyInfoStatus=PPCGetObjectAttrs(MyObject,
  299.                                        &MyInfo,
  300.                                        MyTags);
  301.  
  302. //        Printf("Find New Symbol Status=%ld\n",MyInfoStatus);
  303.       }
  304.  
  305.  
  306.       DisAssTags(PPCDissHandle,
  307.                  DISASS_BUFFER,LineBuffer,
  308.                  TAG_DONE);
  309.       if (MyInfoStatus)
  310.       {
  311.         Printf("%s+0x%lx: %s\n",
  312.                MyInfo.Name,
  313.                Address - MyInfo.Address,
  314.                LineBuffer);
  315.       }
  316.       else
  317.       {
  318.         if (Address < 0xfff00000 || Address >= 0xfff10000)
  319.         {
  320.           Printf("0x%lx: %s\n",
  321.                  Address,
  322.                  LineBuffer);
  323.         }
  324.         else
  325.         { 
  326.           MyInfo.Name        =    "Kernel";
  327.           MyInfo.Address    =    0xfff00000;
  328.           MyInfo.Size        =    0x10000;
  329.           /* Setting MyInfoStatus to false
  330.            * has the effect that it searches again for symbols
  331.            * otherwise it would find dynamic link symbols after
  332.            * it showed a kernel symbol
  333.            */
  334.           MyInfoStatus        =    FALSE;
  335.           Printf("%s+0x%lx: %s\n",
  336.                  MyInfo.Name,
  337.                  Address - MyInfo.Address,
  338.                  LineBuffer);
  339.         }
  340.       }
  341.       Address    +=    4;
  342.     }
  343.     DeleteDisAssHandle(PPCDissHandle);
  344.     NewPC    =    Address;
  345.     return(TRUE);
  346.   }
  347.   else
  348.   {
  349.     return(FALSE);
  350.   }
  351. }
  352.  
  353. BOOL    ShowMem(ULONG    Address,
  354.                 ULONG    Lines)
  355. {
  356. int    i;
  357.   for (i=0;i<Lines;i++)
  358.   {
  359.     Printf("%08lx: %08lx %08lx %08lx %08lx\n",
  360.            Address,
  361.            PPCReadLong((ULONG*) (Address+0x00)),
  362.            PPCReadLong((ULONG*) (Address+0x04)),
  363.            PPCReadLong((ULONG*) (Address+0x08)),
  364.            PPCReadLong((ULONG*) (Address+0x0c)));
  365.     Address    +=    16;
  366.   }
  367.   return(TRUE);
  368. }
  369.  
  370.  
  371. /*------------------------------------------------------------------------*/
  372. /*------------------------------------------------------------------------*/
  373. /*------------------------------------------------------------------------*/
  374. /*------------------------------------------------------------------------*/
  375. /*------------------------------------------------------------------------*/
  376. /*------------------------------------------------------------------------*/
  377. /*------------------------------------------------------------------------*/
  378. /*------------------------------------------------------------------------*/
  379.  
  380. void    ShowRegsGPR(void)
  381. {
  382. int    i;
  383.   for (i=0;i<32;i+=8)
  384.   {
  385.     Printf("GPR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  386.            ExceptionMsg.GPR[i+0],
  387.            ExceptionMsg.GPR[i+1],
  388.            ExceptionMsg.GPR[i+2],
  389.            ExceptionMsg.GPR[i+3],
  390.            ExceptionMsg.GPR[i+4],
  391.            ExceptionMsg.GPR[i+5],
  392.            ExceptionMsg.GPR[i+6],
  393.            ExceptionMsg.GPR[i+7]);
  394.   }
  395. }
  396.  
  397. void    ShowRegsFPR(void)
  398. {
  399. int    i;
  400.   if (ExceptionMsg.SRR1 & MSRF_FP)
  401.   {
  402.     Printf("FPSCR %08lx\n",
  403.           ExceptionMsg.FPSCR);
  404.  
  405.     for (i=0;i<32;i+=8)
  406.     {
  407.       printf("FPR %g %g %g %g %g %g %g %g\n",
  408.              ExceptionMsg.FPR[i+0],
  409.              ExceptionMsg.FPR[i+1],
  410.              ExceptionMsg.FPR[i+2],
  411.              ExceptionMsg.FPR[i+3],
  412.              ExceptionMsg.FPR[i+4],
  413.              ExceptionMsg.FPR[i+5],
  414.              ExceptionMsg.FPR[i+6],
  415.              ExceptionMsg.FPR[i+7]);
  416.     }
  417.   }
  418. }
  419.  
  420. void    ShowRegsFPRHex(void)
  421. {
  422. int    i;
  423.   if (ExceptionMsg.SRR1 & MSRF_FP)
  424.   {
  425.     Printf("FPSCR %08lx\n",
  426.             ExceptionMsg.FPSCR);
  427.  
  428.     for (i=0;i<32;i+=4)
  429.     {
  430.       printf("FPR 0x%08lx%08lx 0x%08lx%08lx 0x%08lx%08lx 0x%08lx%08lx\n",
  431.              ((ULONG*) &ExceptionMsg.FPR[i+0])[0],((ULONG*) &ExceptionMsg.FPR[i+0])[1],
  432.              ((ULONG*) &ExceptionMsg.FPR[i+1])[0],((ULONG*) &ExceptionMsg.FPR[i+1])[1],
  433.              ((ULONG*) &ExceptionMsg.FPR[i+2])[0],((ULONG*) &ExceptionMsg.FPR[i+2])[1],
  434.              ((ULONG*) &ExceptionMsg.FPR[i+3])[0],((ULONG*) &ExceptionMsg.FPR[i+3])[1]);
  435.     }
  436.   }
  437. }
  438.  
  439. void    ShowRegsMMU(void)
  440. {
  441.   Printf("SDR1 %08lx\n",
  442.          ExceptionMsg.SDR1);
  443.  
  444.  
  445.   if (FALSE)
  446.   {
  447.     /* 64bit CPU */
  448.     Printf("ASR %08lx\n",
  449.            ExceptionMsg.ASR);
  450.   }
  451.  
  452.   if ((CPU==CPU_603) ||
  453.       (CPU==CPU_603e) ||
  454.       (CPU==CPU_603p))
  455.   {
  456.     Printf("DMISS %08lx DCMP %08lx IMISS %08lx ICMP %08lx\n",
  457.            ExceptionMsg.DMISS,
  458.            ExceptionMsg.DCMP,
  459.            ExceptionMsg.IMISS,
  460.            ExceptionMsg.ICMP);
  461.  
  462.     Printf("HASH1 %08lx HASH2 %08lx RPA %08lx\n",
  463.            ExceptionMsg.HASH1,
  464.            ExceptionMsg.HASH2,
  465.            ExceptionMsg.RPA);
  466.   }
  467.  
  468.   Printf("IBAT0U %08lx IBAT0L %08lx IBAT1U %08lx IBAT1L %08lx\n",
  469.          ExceptionMsg.IBAT0U,
  470.          ExceptionMsg.IBAT0L,
  471.          ExceptionMsg.IBAT1U,
  472.          ExceptionMsg.IBAT1L);
  473.  
  474.   Printf("IBAT2U %08lx IBAT2L %08lx IBAT3U %08lx IBAT3L %08lx\n",
  475.          ExceptionMsg.IBAT2U,
  476.          ExceptionMsg.IBAT2L,
  477.          ExceptionMsg.IBAT3U,
  478.          ExceptionMsg.IBAT3L);
  479.  
  480.   Printf("DBAT0U %08lx DBAT0L %08lx DBAT1U %08lx DBAT1L %08lx\n",
  481.          ExceptionMsg.DBAT0U,
  482.          ExceptionMsg.DBAT0L,
  483.          ExceptionMsg.DBAT1U,
  484.          ExceptionMsg.DBAT1L);
  485.  
  486.   Printf("DBAT2U %08lx DBAT2L %08lx DBAT3U %08lx DBAT3L %08lx\n",
  487.          ExceptionMsg.DBAT2U,
  488.          ExceptionMsg.DBAT2L,
  489.          ExceptionMsg.DBAT3U,
  490.          ExceptionMsg.DBAT3L);
  491.  
  492.   Printf("SR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  493.          ExceptionMsg.SR[0],
  494.          ExceptionMsg.SR[1],
  495.          ExceptionMsg.SR[2],
  496.          ExceptionMsg.SR[3],
  497.          ExceptionMsg.SR[4],
  498.          ExceptionMsg.SR[5],
  499.          ExceptionMsg.SR[6],
  500.          ExceptionMsg.SR[7]);
  501.  
  502.   Printf("SR %08lx %08lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  503.          ExceptionMsg.SR[8],
  504.          ExceptionMsg.SR[9],
  505.          ExceptionMsg.SR[10],
  506.          ExceptionMsg.SR[11],
  507.          ExceptionMsg.SR[12],
  508.          ExceptionMsg.SR[13],
  509.          ExceptionMsg.SR[14],
  510.          ExceptionMsg.SR[15]);
  511.  
  512. }
  513.  
  514. void    ShowRegsMisc(void)
  515. {
  516.   Printf("PVR %08lx\n",
  517.          ExceptionMsg.PVR);
  518.  
  519.   Printf("SPRG0 %08lx SPRG1 %08lx SPRG2 %08lx SPRG3 %08lx\n",
  520.          ExceptionMsg.SPRG0,
  521.          ExceptionMsg.SPRG1,
  522.          ExceptionMsg.SPRG2,
  523.          ExceptionMsg.SPRG3);
  524.  
  525.   Printf("TBL %08lx TBU %08lx DEC %08lx DABA %08lx\n",
  526.          ExceptionMsg.TBL,
  527.          ExceptionMsg.TBU,
  528.          ExceptionMsg.DEC,
  529.          ExceptionMsg.DABR);
  530. }
  531.  
  532. void    ShowRegsFrame(void)
  533. {
  534.   Printf("PC %08lx MSR %08lx DAR %08lx DSISR %08lx\n",
  535.          ExceptionMsg.SRR0,
  536.          ExceptionMsg.SRR1,
  537.          ExceptionMsg.DAR,
  538.          ExceptionMsg.DSISR);
  539.  
  540.   Printf("CR %08lx XER %08lx LR %08lx CTR %08lx\n",
  541.          ExceptionMsg.CR,
  542.          ExceptionMsg.XER,
  543.          ExceptionMsg.LR,
  544.          ExceptionMsg.CTR);
  545. }
  546.  
  547. void    ShowRegs(void)
  548. {
  549.   if (ShowRegFormat & SHOWREG_FRAME)
  550.   {
  551.     ShowRegsFrame();
  552.   }
  553.   if (ShowRegFormat & SHOWREG_GPR)
  554.   {
  555.     ShowRegsGPR();
  556.   }
  557.   if (ShowRegFormat & SHOWREG_FPUHEX)
  558.   {
  559.     ShowRegsFPRHex();
  560.   }
  561.   if (ShowRegFormat & SHOWREG_FPU)
  562.   {
  563.     ShowRegsFPR();
  564.   }
  565.   if (ShowRegFormat & SHOWREG_MMU)
  566.   {
  567.     ShowRegsMMU();
  568.   }
  569.   if (ShowRegFormat & SHOWREG_MISC)
  570.   {
  571.     ShowRegsMMU();
  572.   }
  573.   ShowDiss(ExceptionMsg.SRR0,
  574.            1,
  575.            FALSE);
  576. }
  577.  
  578.  
  579. /*------------------------------------------------------------------------*/
  580. /*------------------------------------------------------------------------*/
  581. /*------------------------------------------------------------------------*/
  582. /*------------------------------------------------------------------------*/
  583. /*------------------------------------------------------------------------*/
  584. /*------------------------------------------------------------------------*/
  585. /*------------------------------------------------------------------------*/
  586. /*------------------------------------------------------------------------*/
  587.  
  588. BOOL    AddBreakPoint(ULONG    *Address)
  589. {
  590. struct BreakPoint    *MyBreakPoint;
  591.  
  592.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  593.   while (MyBreakPoint->Node.ln_Succ)
  594.   {
  595.     if (MyBreakPoint->Address == Address)
  596.     {
  597.       return(TRUE);
  598.     }
  599.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  600.   }
  601.  
  602.   if (MyBreakPoint=(struct BreakPoint*) AllocVec(sizeof(struct BreakPoint),MEMF_PUBLIC))
  603.   {
  604. //  __builtin_emit(0x4afc);
  605.     AddTail(&BreakPointList,
  606.             &MyBreakPoint->Node);
  607.  
  608.     MyBreakPoint->Address    =    Address;
  609.     MyBreakPoint->Opcode    =    PPCReadLong(MyBreakPoint->Address);
  610.  
  611.     PPCWriteLongFlush((ULONG*) MyBreakPoint->Address,
  612.                       OPCODE_TD31_0_0);
  613.     return(TRUE);
  614.   }
  615.   else
  616.   {
  617.     return(FALSE);
  618.   }
  619. }
  620.  
  621. BOOL    RemoveBreakPoint(ULONG    *Address)
  622. {
  623. struct BreakPoint    *MyBreakPoint;
  624.  
  625.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  626.   while (MyBreakPoint->Node.ln_Succ)
  627.   {
  628.     if (MyBreakPoint->Address == Address)
  629.     {
  630.       Remove(&MyBreakPoint->Node);
  631.  
  632.       PPCWriteLongFlush(MyBreakPoint->Address,
  633.                         MyBreakPoint->Opcode);
  634.  
  635.       FreeVec(MyBreakPoint);
  636.       return(TRUE);
  637.     }
  638.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  639.   }
  640.   return(FALSE);
  641. }
  642.  
  643. void    RemoveBreakPointAll(void)
  644. {
  645. struct BreakPoint    *MyBreakPoint;
  646. struct BreakPoint    *MyBreakPointSave;
  647.  
  648.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  649.   while (MyBreakPoint->Node.ln_Succ)
  650.   {
  651.     Remove(&MyBreakPoint->Node);
  652.     MyBreakPointSave    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  653.     FreeVec(MyBreakPoint);
  654.     MyBreakPoint    =    MyBreakPointSave;
  655.   }
  656. }
  657.  
  658. void    ShowBreakPointAll(void)
  659. {
  660. struct BreakPoint    *MyBreakPoint;
  661.  
  662.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  663.   while (MyBreakPoint->Node.ln_Succ)
  664.   {
  665.     printf("Breakpoint at 0x%08lx with saved Opcode 0x%08lx\n",
  666.            MyBreakPoint->Address,
  667.            MyBreakPoint->Opcode);
  668.  
  669.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  670.   }
  671. }
  672.  
  673.  
  674. struct BreakPoint    *CheckBreakPoint(ULONG    *Address)
  675. {
  676. struct BreakPoint    *MyBreakPoint;
  677.  
  678.   MyBreakPoint    =(struct BreakPoint*) BreakPointList.lh_Head;
  679.   while (MyBreakPoint->Node.ln_Succ)
  680.   {
  681.     if (MyBreakPoint->Address == Address)
  682.     {
  683.       return(MyBreakPoint);
  684.     }
  685.     MyBreakPoint    =(struct BreakPoint*) MyBreakPoint->Node.ln_Succ;
  686.   }
  687.   return(NULL);
  688. }
  689.  
  690.  
  691.  
  692. /*------------------------------------------------------------------------*/
  693. /*------------------------------------------------------------------------*/
  694. /*------------------------------------------------------------------------*/
  695. /*------------------------------------------------------------------------*/
  696. /*------------------------------------------------------------------------*/
  697. /*------------------------------------------------------------------------*/
  698. /*------------------------------------------------------------------------*/
  699. /*------------------------------------------------------------------------*/
  700.  
  701.  
  702. BOOL __asm ExceptionHookFunc(register __a0 struct Hook        *MyHook,
  703.                              register __a2 void            *MyTask,
  704.                              register __a1 struct ExceptionMsg    *MyMsg)
  705. {
  706.   ExceptionTask    =    MyTask;
  707.  
  708.   CopyMem(MyMsg,
  709.           &ExceptionMsg,
  710.           sizeof(struct ExceptionMsg));
  711.  
  712.   if (MsgProcess)
  713.   {
  714.     Signal(&MsgProcess->pr_Task,
  715.            1<<SIGNAL_EXCEPTION);
  716.     return(TRUE);
  717.   }
  718.   else
  719.   {
  720.     return(FALSE);
  721.   }
  722. }
  723.  
  724. /*------------------------------------------------------------------------*/
  725. /*------------------------------------------------------------------------*/
  726. /*------------------------------------------------------------------------*/
  727. /*------------------------------------------------------------------------*/
  728. /*------------------------------------------------------------------------*/
  729. /*------------------------------------------------------------------------*/
  730. /*------------------------------------------------------------------------*/
  731. /*------------------------------------------------------------------------*/
  732.  
  733.  
  734. ULONG    __asm AddressHookFunc(register __a0 struct Hook        *MyHook,
  735.                               register __a2 char        *MyBuffer,
  736.                               register __a1 ULONG        PC)
  737. {
  738.   return(0);
  739. }
  740.  
  741.  
  742. /*------------------------------------------------------------------------*/
  743. /*------------------------------------------------------------------------*/
  744. /*------------------------------------------------------------------------*/
  745. /*------------------------------------------------------------------------*/
  746. /*------------------------------------------------------------------------*/
  747. /*------------------------------------------------------------------------*/
  748. /*------------------------------------------------------------------------*/
  749. /*------------------------------------------------------------------------*/
  750.  
  751. ULONG    __asm SymbolHookFunc(register __a0 struct Hook        *MyHook,
  752.                              register __a2 char            *MyBuffer,
  753.                              register __a1 ULONG        PC)
  754. {
  755. struct PPCObjectInfo    MyInfo;
  756. struct TagItem        MyTags[1];
  757.  
  758.   MyInfo.Address    =    PC;
  759.   MyInfo.Name        =    NULL;
  760.   MyTags[0].ti_Tag    =    TAG_END;
  761.  
  762.   if (PPCGetObjectAttrs(MyObject,
  763.                         &MyInfo,
  764.                         MyTags))
  765.   {
  766. //  __builtin_emit(0x4afc);
  767.     if (PC == MyInfo.Address)
  768.     {
  769.       return((ULONG) sprintf(MyBuffer,"%s",
  770.                              MyInfo.Name));
  771.     }
  772.     else
  773.     {
  774.       return((ULONG) sprintf(MyBuffer,"%s+0x%lx",
  775.                              MyInfo.Name,
  776.                              PC - MyInfo.Address));
  777.     }
  778.   }
  779.   else
  780.   {
  781.     return(0);
  782.   }
  783. }
  784.  
  785. /*------------------------------------------------------------------------*/
  786. /*------------------------------------------------------------------------*/
  787. /*------------------------------------------------------------------------*/
  788. /*------------------------------------------------------------------------*/
  789. /*------------------------------------------------------------------------*/
  790. /*------------------------------------------------------------------------*/
  791. /*------------------------------------------------------------------------*/
  792. /*------------------------------------------------------------------------*/
  793.  
  794. ULONG    __asm RelocHookFunc(register __a0 struct Hook        *MyHook,
  795.                             register __a2 char            *MyBuffer,
  796.                             register __a1 ULONG            PC)
  797. {
  798. struct PPCObjectInfo    MyInfo;
  799. struct TagItem        MyTags[2];
  800. char            *AddressMode;
  801.  
  802.   MyInfo.Address    =    PC;
  803.   MyInfo.Name        =    NULL;
  804.   MyTags[0].ti_Tag    =    PPCELFINFOTAG_RELOC;
  805.   MyTags[0].ti_Data    =    TRUE;
  806.   MyTags[1].ti_Tag    =    TAG_END;
  807.  
  808. //  __builtin_emit(0x4afc);
  809.   if (PPCGetObjectAttrs(MyObject,
  810.                         &MyInfo,
  811.                         MyTags))
  812.   {
  813.     switch (MyInfo.SubType)
  814.     {
  815.       case    R_PPC_ADDR16_L:
  816.                 AddressMode    =    "@l";
  817.                 break;
  818.  
  819.       case    R_PPC_ADDR16_HI:
  820.                 AddressMode    =    "@hi";
  821.                 break;
  822.  
  823.       case    R_PPC_ADDR16_HA:
  824.                 AddressMode    =    "@ha";
  825.                 break;
  826.  
  827.       default:
  828.                 AddressMode    =    "";
  829.                 break;
  830.  
  831.     } 
  832.     return((ULONG) sprintf(MyBuffer,"%s%s",
  833.                            MyInfo.Name,
  834.                            AddressMode));
  835.   }
  836.   return(0);
  837. }
  838.  
  839. /*------------------------------------------------------------------------*/
  840. /*------------------------------------------------------------------------*/
  841. /*------------------------------------------------------------------------*/
  842. /*------------------------------------------------------------------------*/
  843. /*------------------------------------------------------------------------*/
  844. /*------------------------------------------------------------------------*/
  845. /*------------------------------------------------------------------------*/
  846. /*------------------------------------------------------------------------*/
  847.  
  848. void    __asm ScanHookFunc(register __a0 struct Hook        *MyHook,
  849.                            register __a2 void            *MyElfStruct,
  850.                            register __a1 struct PPCObjectInfo    *MyInfo)
  851.                             
  852. {
  853.   Printf("0x%08lx\t0x%08lx\t%s\n",
  854.          MyInfo->Address,
  855.          MyInfo->Size,
  856.          MyInfo->Name);
  857.  
  858. }
  859.  
  860. /*------------------------------------------------------------------------*/
  861. /*------------------------------------------------------------------------*/
  862. /*------------------------------------------------------------------------*/
  863. /*------------------------------------------------------------------------*/
  864. /*------------------------------------------------------------------------*/
  865. /*------------------------------------------------------------------------*/
  866. /*------------------------------------------------------------------------*/
  867. /*------------------------------------------------------------------------*/
  868.  
  869. BOOL    __asm ArgParserSymbolHookFunc(register __a0 struct Hook            *MyHook,
  870.                                       register __a2 char            *MyBuffer,
  871.                                       register __a1 struct SymbolHookMsg    *MyMsg)
  872. {
  873. char            LineBuffer[128];
  874. char            a;
  875. int            Length;
  876. struct TagItem        MyTags[1];
  877. struct PPCObjectInfo    MyInfo;
  878.  
  879.   Length=0;
  880.   while (((a=MyBuffer[Length]) >= 'a' && MyBuffer[Length] <= 'z') ||
  881.          (MyBuffer[Length] >= 'A' && MyBuffer[Length] <= 'Z') ||
  882.          (MyBuffer[Length] >= '0' && MyBuffer[Length] <= '9') ||
  883.          (MyBuffer[Length] >= '_'))
  884.   {
  885.     LineBuffer[Length]    =    a;
  886.     Length++;
  887.     if (Length > 126)
  888.     {
  889.       MyMsg->Error    =    ERROR_SYMBOLTOOLONG;
  890.       return(FALSE);
  891.     }
  892.   }
  893.   LineBuffer[Length]    =    '\0';
  894.   MyMsg->Length        =    Length;
  895.  
  896.   MyInfo.Name        =    LineBuffer;
  897.   MyInfo.Address    =    NULL;
  898.  
  899.   if (PPCGetObjectAttrs(MyObject,
  900.                         &MyInfo,
  901.                         MyTags))
  902.   {
  903. //    __builtin_emit(0x4afc);
  904.     MyMsg->Type        =    PARSETYPE_INTEGER;
  905.     *MyMsg->Integer    =    MyInfo.Address;
  906.     return(TRUE);
  907.   }
  908.   else
  909.   {
  910.     MyMsg->Error    =    ERROR_UNKNOWNSYMBOL;
  911.     return(FALSE);
  912.   }
  913.  
  914. }
  915.  
  916. /*------------------------------------------------------------------------*/
  917. /*------------------------------------------------------------------------*/
  918. /*------------------------------------------------------------------------*/
  919. /*------------------------------------------------------------------------*/
  920. /*------------------------------------------------------------------------*/
  921. /*------------------------------------------------------------------------*/
  922. /*------------------------------------------------------------------------*/
  923. /*------------------------------------------------------------------------*/
  924.  
  925. ULONG    __asm GetDataHookFunc(register __a0 struct Hook            *MyHook,
  926.                               register __a2 ULONG            *Address,
  927.                               register __a1 void            *Nobodycares)
  928. {
  929. struct BreakPoint    *MyBreakPoint;
  930.  
  931.   if (MyBreakPoint=CheckBreakPoint(Address))
  932.   {
  933.     return(MyBreakPoint->Opcode);
  934.   }
  935.   else
  936.   {
  937.     return(*Address);
  938.   }
  939. }
  940.  
  941.  
  942. /*------------------------------------------------------------------------*/
  943. /*------------------------------------------------------------------------*/
  944. /*------------------------------------------------------------------------*/
  945. /*------------------------------------------------------------------------*/
  946. /*------------------------------------------------------------------------*/
  947. /*------------------------------------------------------------------------*/
  948. /*------------------------------------------------------------------------*/
  949. /*------------------------------------------------------------------------*/
  950.  
  951. void    HandleInput(void)
  952. {
  953. char        MyBuffer[LINEMAX];
  954. struct TagItem    MyTags[10];
  955. ULONG        Value;
  956. ULONG        Length;
  957. ULONG        Lines;
  958. ULONG        Register;
  959. char        *Ptr;
  960. char        CMD;
  961. ULONG        Command;
  962. ULONG        CommandWord;
  963. ULONG        *TracePointAddress;
  964.  
  965. /*
  966.  * Each Exception set the default PC
  967.  */
  968.   PC        =    ExceptionMsg.SRR0;
  969.   MEM        =    ExceptionMsg.DAR;
  970.  
  971.   for (;;)
  972.   {
  973.     Printf(">");
  974.     Flush(OutputFile);
  975.     if (Length=Read(InputFile,&MyBuffer[0],LINEMAX))
  976.     {
  977.       MyBuffer[Length-1]    =    0;
  978.  
  979.       switch (tolower(MyBuffer[0]))
  980.       {
  981.         case    'g':
  982.                 if (tolower(MyBuffer[1]) == 's')
  983.                 {
  984.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  985.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  986.                   MyTags[0].ti_Data    =    TRUE;
  987.                   MyTags[1].ti_Tag    =    TAG_END;
  988.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  989.                   GoSimulateFlag    =    TRUE;
  990.                   return;
  991.                 }
  992.                 else
  993.                 {
  994.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  995.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_RUN;
  996.                   MyTags[0].ti_Data    =    TRUE;
  997.                   MyTags[1].ti_Tag    =    TAG_END;
  998.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  999.                   return;
  1000.                 }
  1001.                 break;
  1002.  
  1003.         case    's':
  1004.                 MyTracePoint.Address    =    EMPTYTRACEPOINT;
  1005.                 MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  1006.                 MyTags[0].ti_Data    =    TRUE;
  1007.                 MyTags[1].ti_Tag    =    TAG_END;
  1008.                 PPCStartTask(ExceptionTask,&MyTags[0]);
  1009.                 return;
  1010.                 break;
  1011.  
  1012.         case    't':
  1013. //  __builtin_emit(0x4afc);
  1014.                 CommandWord        =    *((ULONG*) ExceptionMsg.SRR0);
  1015.                 Command            =    CommandWord >> (31-5);
  1016.                 if ((Command == 0x10 && !(CommandWord & OPCODE_LR))                                || // bcx BO,BI,addr
  1017.                     (Command == 0x12 && !(CommandWord & OPCODE_LR))                                || // bx addr
  1018.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(1,0,0,0,0,1,0,0,0,0) && !(CommandWord & OPCODE_LR))    || // bcctr
  1019.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(0,0,0,0,0,1,0,0,0,0) && !(CommandWord & OPCODE_LR))    || // bclrx
  1020.                     (Command == 0x13 && MASK_21_30(CommandWord)== OP_ID(0,0,0,0,1,1,0,0,1,0)))                          // rfi
  1021.                 {
  1022.                   /* Use Single Step for commands which change the PC */
  1023.                   MyTracePoint.Address    =    EMPTYTRACEPOINT;
  1024.                   MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  1025.                   MyTags[0].ti_Data    =    TRUE;
  1026.                   MyTags[1].ti_Tag    =    TAG_END;
  1027.                   PPCStartTask(ExceptionTask,&MyTags[0]);
  1028.                 }
  1029.                 else
  1030.                 {
  1031.  
  1032.                   TracePointAddress        =    (ULONG*) (ExceptionMsg.SRR0+4);
  1033.  
  1034.                   /*
  1035.                    * Check if the TracePointAddress is already
  1036.                    * marked in the usual breakpoint list.
  1037.                    * to avoid ugly Breakpoint overloading.
  1038.                    */
  1039.                   if (CheckBreakPoint(TracePointAddress) == NULL)
  1040.                   {
  1041.                     MyTracePoint.Address    =    TracePointAddress;
  1042.                     MyTracePoint.Opcode        =    PPCReadLong(MyTracePoint.Address);
  1043.  
  1044.                     PPCWriteLongFlush((ULONG*) MyTracePoint.Address,
  1045.                                       OPCODE_TD31_0_0);
  1046.  
  1047.                     MyTags[0].ti_Tag        =    PPCTASKSTARTTAG_RUN;
  1048.                     MyTags[0].ti_Data        =    TRUE;
  1049.                     MyTags[1].ti_Tag        =    TAG_END;
  1050.                     PPCStartTask(ExceptionTask,&MyTags[0]);
  1051.                   }
  1052.                 }
  1053.                 return;
  1054.                 break;
  1055.  
  1056. /*
  1057.  * I would have to change the Task/console to handle async events.
  1058.  * No time for this release
  1059.         case    'z':
  1060.                 MyTags[0].ti_Tag    =    TAG_END;
  1061.                 PPCStopTask(ExceptionTask,&MyTags[0]);
  1062.                 return;
  1063.                 break;
  1064.  */
  1065.  
  1066.         case    'd':
  1067. //  __builtin_emit(0x4afc);
  1068.                 if (MyBuffer[1] != 'r')
  1069.                 {
  1070.                   Ptr        =    &MyBuffer[1];
  1071.                   Lines        =    8;
  1072.  
  1073.                   if (Ptr=strtok(Ptr," "))
  1074.                   {
  1075.                     if (GetValue(Ptr,&PC))
  1076.                     {
  1077.                       if (Ptr=strtok(NULL," "))
  1078.                       {
  1079.                         GetValue(Ptr,&Lines);
  1080.                       }
  1081.                     }
  1082.                   }
  1083.                 }
  1084.                 else
  1085.                 {
  1086.                   PC    =    ExceptionMsg.LR;
  1087.                   Lines    =    8;
  1088.  
  1089.                   if (Ptr=strtok(&MyBuffer[2]," "))
  1090.                   {
  1091.                     GetValue(Ptr,&Lines);
  1092.                   }
  1093.                 }
  1094.  
  1095.                 if (ShowDiss(PC,
  1096.                              Lines,
  1097.                              TRUE))
  1098.                 {
  1099.                   PC        =    NewPC;
  1100.                 }
  1101.                 break;
  1102.  
  1103.  
  1104.         case    'm':
  1105.                 Ptr        =    &MyBuffer[1];
  1106.                 Lines        =    8;
  1107.  
  1108.                 if (Ptr=strtok(Ptr," "))
  1109.                 {
  1110.                   if (GetValue(Ptr,&MEM))
  1111.                   {
  1112.                     if (Ptr=strtok(NULL," "))
  1113.                     {
  1114.                       GetValue(Ptr,&Lines);
  1115.                     }
  1116.                   }
  1117.                 }
  1118.                 ShowMem(MEM,Lines);
  1119.                 break;
  1120.  
  1121.         case    'f':
  1122.                 {
  1123.                   struct PPCObjectInfo    MyInfo;
  1124.  
  1125.                   MyTags[0].ti_Tag    =    PPCELFINFOTAG_SCANSYMBOLHOOK;
  1126.                   MyTags[0].ti_Data    =    (ULONG) &MyScanSymbolHook;
  1127.                   MyTags[1].ti_Tag    =    TAG_END;
  1128.                   MyInfoStatus=PPCGetObjectAttrs(MyObject,
  1129.                                                  &MyInfo,
  1130.                                                  MyTags);
  1131.                 }
  1132.                 break;
  1133.  
  1134.         case    'r':
  1135.                 Ptr        =    &MyBuffer[1];
  1136. //  __builtin_emit(0x4afc);
  1137.  
  1138.                 if (Ptr=strtok(Ptr," ="))
  1139.                 {
  1140.                   if (((tolower(MyBuffer[1]) == 'g') || (tolower(MyBuffer[1]) == 'f')) &&
  1141.                        MyBuffer[2] == '[')
  1142.                   {
  1143.                     if (Length=stcd_l(&MyBuffer[3],(long*) &Register))
  1144.                     {
  1145.                       if ((Register <= 31) &&
  1146.                           MyBuffer[3+Length] == ']')
  1147.                       {
  1148.                         Ptr        =    &MyBuffer[3+Length+1];
  1149.                         if (Ptr=strtok(NULL," "))
  1150.                         {
  1151.                           ULONG        Error;
  1152.                           ULONG        Value;
  1153.                           double    DValue;
  1154.                           ULONG        Type;
  1155.                           void        *MyParseHandle;
  1156.  
  1157.                           MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1158.                           MyTags[0].ti_Data    =    (ULONG) &Error;
  1159.                           MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1160.  
  1161.                           if (tolower(MyBuffer[1]) == 'g')
  1162.                           {
  1163.                             Type        =    PARSETYPE_INTEGER;
  1164.                             MyTags[1].ti_Data    =    (ULONG) &Value;
  1165.                           }
  1166.                           else
  1167.                           {
  1168.                             Type        =    PARSETYPE_DOUBLE;
  1169.                             MyTags[1].ti_Data    =    (ULONG) &DValue;
  1170.                           }
  1171.  
  1172.                           MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1173.                           MyTags[2].ti_Data    =    (ULONG) &Type;
  1174.                           MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1175.                           MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1176.                           MyTags[4].ti_Tag    =    TAG_END;
  1177.  
  1178.                           if (MyParseHandle=CreateParseHandle(MyTags))
  1179.                           {
  1180.                             MyTags[0].ti_Tag    =    TAG_END;
  1181.                             if (ParseArgument(MyParseHandle,
  1182.                                               Ptr,
  1183.                                               MyTags))
  1184.                             {
  1185.                               if (tolower(MyBuffer[1] == 'g'))
  1186.                               {
  1187.                                 printf("GPR[%ld] = 0x%08lx\n",
  1188.                                        Register,
  1189.                                        Value);
  1190.  
  1191.                                 ExceptionMsg.GPR[Register]    =    Value;
  1192.                                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_GPR;
  1193.                                 MyTags[0].ti_Data        =    Register;
  1194.                                 MyTags[1].ti_Tag        =    PPCTASKINFOTAG_VALUEPTR;
  1195.                                 MyTags[1].ti_Data        =    (ULONG) &Value;
  1196.                                 MyTags[2].ti_Tag        =    TAG_END;
  1197.                                 PPCSetTaskAttrs(ExceptionTask,
  1198.                                                 MyTags);
  1199.                               }
  1200.                               else
  1201.                               {
  1202.                                 printf("FPR[%ld] = %g\n",
  1203.                                        Register,
  1204.                                        DValue);
  1205.  
  1206.                                 ExceptionMsg.FPR[Register]    =    DValue;
  1207.                                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_FPR;
  1208.                                 MyTags[0].ti_Data        =    Register;
  1209.                                 MyTags[1].ti_Tag        =    PPCTASKINFOTAG_VALUEPTR;
  1210.                                 MyTags[1].ti_Data        =    (ULONG) &DValue;
  1211.                                 MyTags[2].ti_Tag        =    TAG_END;
  1212.                                 PPCSetTaskAttrs(ExceptionTask,
  1213.                                                MyTags);
  1214.                               }
  1215.                             }
  1216.                             else
  1217.                             {
  1218.                               printf("Error 0x%08lx\n",Error);
  1219.                             }
  1220.                             DeleteParseHandle(MyParseHandle);
  1221.                           }
  1222.                         }
  1223.                       }
  1224.                     }
  1225.                   }
  1226.                   else if (MyBuffer[1] == 'g')
  1227.  
  1228.                   {
  1229.                     ShowRegsGPR();
  1230.                   }
  1231.                   else if (MyBuffer[1] == 'f')
  1232.  
  1233.                   {
  1234.                     ShowRegsFPR();
  1235.                   }
  1236.                 }
  1237.                 else
  1238.                 {
  1239.                   ShowRegs();
  1240.                 }
  1241.                 break;
  1242.  
  1243.  
  1244.         case    '+':
  1245.                 ExceptionMsg.SRR0        +=    4;
  1246.                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_PC;
  1247.                 MyTags[0].ti_Data        =    (ULONG) &ExceptionMsg.SRR0;
  1248.                 MyTags[1].ti_Tag        =    TAG_END;
  1249.                 PPCSetTaskAttrs(ExceptionTask,
  1250.                                MyTags);
  1251.                 break;
  1252.  
  1253.         case    '-':
  1254.                 ExceptionMsg.SRR0        -=    4;
  1255.                 MyTags[0].ti_Tag        =    PPCTASKINFOTAG_PC;
  1256.                 MyTags[0].ti_Data        =    (ULONG) &ExceptionMsg.SRR0;
  1257.                 MyTags[1].ti_Tag        =    TAG_END;
  1258.                 PPCSetTaskAttrs(ExceptionTask,
  1259.                                MyTags);
  1260.                 break;
  1261.  
  1262.         case    '#':
  1263.                 CMD    =    MyBuffer[1];
  1264.                 if (CMD == '+')
  1265.                 {
  1266.                   Ptr    =    &MyBuffer[2];
  1267.                 }
  1268.                 else
  1269.                 if (CMD == '-')
  1270.                 {
  1271.                   Ptr    =    &MyBuffer[2];
  1272.                 }
  1273.                 else
  1274.                 {
  1275.                   Ptr    =    &MyBuffer[1];
  1276.                 }
  1277.  
  1278.                 if (Ptr=strtok(Ptr," "))
  1279.                 {
  1280.                   GetValue(Ptr,&Value);
  1281.                 }
  1282.  
  1283.                 if (CMD == '+')
  1284.                 {
  1285.                   ShowRegFormat    |=    Value;
  1286.                 }
  1287.                 else
  1288.                 if (CMD == '-')
  1289.                 {
  1290.                   ShowRegFormat    &=    ~Value;
  1291.                 }
  1292.                 else
  1293.                 {
  1294.                   ShowRegFormat    =    Value;
  1295.                 }
  1296.  
  1297.                 break;
  1298.  
  1299.         case    '?':
  1300.                 Ptr        =    &MyBuffer[1];
  1301.                 if (Ptr=strtok(Ptr," "))
  1302.                 {
  1303.                   ULONG    Error;
  1304.                   ULONG    Value;
  1305.                   ULONG    Type;
  1306.                   void    *MyParseHandle;
  1307.  
  1308.                   Type            =    PARSETYPE_INTEGER;
  1309.                   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1310.                   MyTags[0].ti_Data    =    (ULONG) &Error;
  1311.                   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1312.                   MyTags[1].ti_Data    =    (ULONG) &Value;
  1313.                   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1314.                   MyTags[2].ti_Data    =    (ULONG) &Type;
  1315.                   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1316.                   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1317.                   MyTags[4].ti_Tag    =    TAG_END;
  1318.  
  1319.                   if (MyParseHandle=CreateParseHandle(MyTags))
  1320.                   {
  1321.                     MyTags[0].ti_Tag    =    TAG_END;
  1322.                     if (ParseArgument(MyParseHandle,
  1323.                                       Ptr,
  1324.                                       MyTags))
  1325.                     {
  1326.                       printf("= 0x%08lx\n",Value);
  1327.                     }
  1328.                     else
  1329.                     {
  1330.                       printf("Error 0x%08lx\n",Error);
  1331.                     }
  1332.                     DeleteParseHandle(MyParseHandle);
  1333.                   }
  1334.                 }
  1335.                 break;
  1336.  
  1337.  
  1338.         case    'b':
  1339.                 if (MyBuffer[1]=='s')
  1340.                 {
  1341.                   ShowBreakPointAll();
  1342.                   break;
  1343.                 }
  1344.  
  1345.                 if (MyBuffer[1]=='r')
  1346.                 {
  1347.                   Ptr        =    &MyBuffer[2];
  1348.                 }
  1349.                 else
  1350.                 {
  1351.                   Ptr        =    &MyBuffer[1];
  1352.                 }
  1353.                 if (Ptr=strtok(Ptr," "))
  1354.                 {
  1355.                   ULONG    Error;
  1356.                   ULONG    Value;
  1357.                   ULONG    Type;
  1358.                   void    *MyParseHandle;
  1359.  
  1360.                   Type            =    PARSETYPE_INTEGER;
  1361.                   MyTags[0].ti_Tag    =    PARSETAG_ERROR;
  1362.                   MyTags[0].ti_Data    =    (ULONG) &Error;
  1363.                   MyTags[1].ti_Tag    =    PARSETAG_VALUE;
  1364.                   MyTags[1].ti_Data    =    (ULONG) &Value;
  1365.                   MyTags[2].ti_Tag    =    PARSETAG_TYPE;
  1366.                   MyTags[2].ti_Data    =    (ULONG) &Type;
  1367.                   MyTags[3].ti_Tag    =    PARSETAG_SYMBOLHOOK;
  1368.                   MyTags[3].ti_Data    =    (ULONG) &MyArgParserSymbolHook;
  1369.                   MyTags[4].ti_Tag    =    TAG_END;
  1370.  
  1371.                   if (MyParseHandle=CreateParseHandle(MyTags))
  1372.                   {
  1373.                     MyTags[0].ti_Tag    =    TAG_END;
  1374.                     if (ParseArgument(MyParseHandle,
  1375.                                       Ptr,
  1376.                                       MyTags))
  1377.                     {
  1378.                       if (MyBuffer[1]=='r')
  1379.                       {
  1380.                         if (RemoveBreakPoint((ULONG*) Value))
  1381.                         {
  1382.                           printf("No Breakpoint at 0x%08lx found\n",Value);
  1383.                         }
  1384.                         else
  1385.                         {
  1386.                           printf("Breakpoint at 0x%08lx removed\n",Value);
  1387.                         }
  1388.                       }
  1389.                       else
  1390.                       {
  1391.                         if (AddBreakPoint((ULONG*) Value))
  1392.                         {
  1393.                           printf("Breakpoint at 0x%08lx added\n",Value);
  1394.                         }
  1395.                       }
  1396.                     }
  1397.                     else
  1398.                     {
  1399.                       printf("Error 0x%08lx\n",Error);
  1400.                     }
  1401.                     DeleteParseHandle(MyParseHandle);
  1402.                   }
  1403.                 }
  1404.                 break;
  1405.  
  1406.  
  1407.         case    'h':
  1408.                 Printf("(h)elp\n");
  1409.                 Printf("(g)o\n");
  1410.                 Printf("(gs) go with single step\n");
  1411.                 Printf("(t)race\n");
  1412.                 Printf("(s)ingle step\n");
  1413.                 Printf("(z)top..sorry..can`t work because of the sync design\n");
  1414.                 Printf("(d)isassemble [Address] [Lines]\n");
  1415.                 Printf("(dr)isassemble-LR-Register [Lines]\n");
  1416.                 Printf("(m)emory [Address] [Lines]\n");
  1417.                 Printf("(r)egister dump\n");
  1418.                 Printf("(rg) show GPR registers\n");
  1419.                 Printf("(rf) show FPR registers\n");
  1420.                 Printf("(rg[GPR Reg] Value) set GPR register\n");
  1421.                 Printf("(rf[FPR Reg] Value) set FPR register\n");
  1422.                 Printf("(b Value) add Breakpoint\n");
  1423.                 Printf("(br Value) remove Breakpoint\n");
  1424.                 Printf("(bs) show Breakpoint\n");
  1425.                 Printf("(f) Symbol dump\n");
  1426.                 Printf("(? Value)\n");
  1427.                 Printf("(+) Next Instruction\n");
  1428.                 Printf("(-) Previous Instruction\n");
  1429.                 Printf("(#(+,-) MISC | MMU | FPUFLOAT | FPUHEX | FRAME | GPR (Enter BitMask Value)\n");
  1430.                 break;
  1431.       }
  1432.     }
  1433.   }
  1434. }
  1435.  
  1436. /*------------------------------------------------------------------------*/
  1437. /*------------------------------------------------------------------------*/
  1438. /*------------------------------------------------------------------------*/
  1439. /*------------------------------------------------------------------------*/
  1440. /*------------------------------------------------------------------------*/
  1441. /*------------------------------------------------------------------------*/
  1442. /*------------------------------------------------------------------------*/
  1443. /*------------------------------------------------------------------------*/
  1444.  
  1445. void MsgTask(void)
  1446. {
  1447. struct Process    *MyTask;
  1448. struct TagItem    MyTags[10];
  1449. ULONG        SignalMask;
  1450. BPTR        OldInputFile;
  1451. BPTR        OldOutputFile;
  1452.  
  1453.  
  1454.   MyTask                =(struct Process*) FindTask(NULL);
  1455.   OldInputFile                =    MyTask->pr_CIS;
  1456.   OldOutputFile                =    MyTask->pr_COS;
  1457.   MyTask->pr_CIS            =    InputFile;
  1458.   MyTask->pr_COS            =    OutputFile;
  1459.   MyInfo.Address            =    0;
  1460.   MyInfo.Size                =    0;
  1461.   MyInfoStatus                =    FALSE;
  1462.   GoSimulateFlag            =    FALSE;
  1463.  
  1464.   MyAddressHook.h_Entry            =    (ULONG (*)(void)) AddressHookFunc;
  1465.   MyAddressHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1466.   MyAddressHook.h_Data            =    (APTR) PPCLibBase;
  1467.  
  1468.   MySymbolHook.h_Entry            =    (ULONG (*)(void)) SymbolHookFunc;
  1469.   MySymbolHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1470.   MySymbolHook.h_Data            =    (APTR) PPCLibBase;
  1471.  
  1472.   MyRelocHook.h_Entry            =    (ULONG (*)(void)) RelocHookFunc;
  1473.   MyRelocHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1474.   MyRelocHook.h_Data            =    (APTR) PPCLibBase;
  1475.  
  1476.   MyScanSymbolHook.h_Entry        =    (ULONG (*)(void)) ScanHookFunc;
  1477.   MyScanSymbolHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1478.   MyScanSymbolHook.h_Data        =    (APTR) PPCLibBase;
  1479.  
  1480.   MyArgParserSymbolHook.h_Entry        =    (ULONG (*)(void)) ArgParserSymbolHookFunc;
  1481.   MyArgParserSymbolHook.h_SubEntry    =    (ULONG (*)(void)) NULL;
  1482.   MyArgParserSymbolHook.h_Data        =    (APTR) PPCLibBase;
  1483.  
  1484.   MyGetDataHook.h_Entry            =    (ULONG (*)(void)) GetDataHookFunc;
  1485.   MyGetDataHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1486.   MyGetDataHook.h_Data            =    (APTR) PPCLibBase;
  1487.  
  1488.  
  1489.   NewList(&BreakPointList);
  1490.  
  1491.   MyTags[0].ti_Tag            =    PPCINFOTAG_CPU;
  1492.   MyTags[1].ti_Tag            =    TAG_END;
  1493.   CPU                    =    PPCGetAttrs((struct TagItem*) &MyTags);
  1494.  
  1495.   /*
  1496.    * Disable Tracepoint
  1497.    */
  1498.   MyTracePoint.Address            =    EMPTYTRACEPOINT;
  1499.  
  1500.   while ((SignalMask=Wait(1<<SIGNAL_EXCEPTION | 1<<SIGBREAKB_CTRL_C)) == 1<<SIGNAL_EXCEPTION)
  1501.   {
  1502.     Printf("----------------------------------------------------------\n");
  1503.     if (!(ExceptionMsg.Type & EXCEPTION_MSG))
  1504.     {
  1505.       /* Hardware Exception */
  1506.  
  1507.       if (MyTracePoint.Address != EMPTYTRACEPOINT)
  1508.       {
  1509.         /*
  1510.          * Remove tracetrap..doesn`t matter if it hit
  1511.          */
  1512.  
  1513.         PPCWriteLongFlush(MyTracePoint.Address,
  1514.                           MyTracePoint.Opcode);
  1515.  
  1516.         MyTracePoint.Address    = EMPTYTRACEPOINT;
  1517.       }
  1518.  
  1519.       RemoveBreakPoint((ULONG*) ExceptionMsg.SRR0);
  1520.  
  1521.       Printf("Exception: Type 0x%lx %s\n",
  1522.              ExceptionMsg.Type,
  1523.              ExceptionMsg.Type > (sizeof(ExceptionStringTable)/4) ? "Illegal ID" : ExceptionStringTable[ExceptionMsg.Type]);
  1524.     }
  1525.     else
  1526.     {
  1527.       /* Kernel Notify Exception */
  1528.     }
  1529.  
  1530.  
  1531.     if (ExceptionMsg.Type != EXCEPTION_FINISHTASK)
  1532.     {
  1533.       if ((ExceptionMsg.Type == EXCEPTION_DATAACCESS) ||
  1534.           (ExceptionMsg.Type == EXCEPTION_INSTRUCTIONACCESS))
  1535.       {
  1536.         Printf("Illegal Memory Access at %08lx\n",
  1537.                 ExceptionMsg.DAR);
  1538.       }
  1539.  
  1540.       if (ExceptionMsg.Type != EXCEPTION_TRACE)
  1541.       {
  1542.         /* Switch off Simulate Mode and stop for a non trace exception
  1543.          */
  1544.         GoSimulateFlag    =    FALSE;
  1545.       }
  1546.  
  1547.  
  1548.       ShowRegs();
  1549.  
  1550.       if (GoSimulateFlag)
  1551.       {
  1552.         MyTracePoint.Address    =    EMPTYTRACEPOINT;
  1553.         MyTags[0].ti_Tag    =    PPCTASKSTARTTAG_TRACE;
  1554.         MyTags[0].ti_Data    =    TRUE;
  1555.         MyTags[1].ti_Tag    =    TAG_END;
  1556.         PPCStartTask(ExceptionTask,&MyTags[0]);
  1557.       }
  1558.       else
  1559.       {
  1560.         HandleInput();
  1561.       }
  1562.     }
  1563.     else
  1564.     {
  1565.       RemoveBreakPointAll();
  1566.       Printf("Task has finished...\n");
  1567.     }
  1568.   }
  1569.   MyTask->pr_CIS    =    OldInputFile;
  1570.   MyTask->pr_COS    =    OldOutputFile;
  1571.   MsgProcess=NULL;
  1572. }
  1573.  
  1574.  
  1575. /*------------------------------------------------------------------------*/
  1576. /*------------------------------------------------------------------------*/
  1577. /*------------------------------------------------------------------------*/
  1578. /*------------------------------------------------------------------------*/
  1579. /*------------------------------------------------------------------------*/
  1580. /*------------------------------------------------------------------------*/
  1581. /*------------------------------------------------------------------------*/
  1582. /*------------------------------------------------------------------------*/
  1583.  
  1584.  
  1585. int    main(void)
  1586. {
  1587. char                *p;
  1588. char                *line;
  1589. char                *MyArgument;
  1590. char                *MyCommandName;
  1591. char                *MyCommandLine;
  1592. char                *MyTaskName;
  1593. ULONG                MyCommandLen;
  1594. ULONG                MyStackSize;
  1595. ULONG                My68kStackSize;
  1596. struct Process            *MyProcess;
  1597. struct CommandLineInterface    *MyCLI;
  1598. char                *rdargs_line;
  1599. int                MyCommandLinelength;
  1600. struct TagItem            MyTags[30];
  1601. ULONG                Result;
  1602. ULONG                Index;
  1603. struct WBStartup        *WBMsg;
  1604. struct WBArg            *MyWBArg;
  1605. BPTR                NewCurrentDir;
  1606. BPTR                OldCurrentDir;
  1607. void                *M68kPort;
  1608. void                *MyStartupMsg;
  1609. struct StartupData        *MyStartupData;
  1610. struct FileHandle        *CurrentInput;
  1611. BPTR                CurrentInputBPTR;
  1612. ULONG                OldBuffer;
  1613. ULONG                OldPosition;
  1614. ULONG                OldEnd;
  1615. struct TagItem            MyInfoTags[1];
  1616. struct PPCObjectInfo        MyInfo;
  1617. BOOL                CTRL_C_CHECK;
  1618.  
  1619.  
  1620.  
  1621.   if (PPCLibBase=OpenLibrary("ppc.library",0))
  1622.   {
  1623.     if (PPCDissBase=OpenLibrary("ppcdiss.library",0L))
  1624.     {
  1625.       MyProcess        = (struct Process*) FindTask(NULL);
  1626.       MyCLI        = (struct CommandLineInterface*) BADDR(MyProcess->pr_CLI);
  1627.       InputFile        =    Input();
  1628.       OutputFile    =    Output();
  1629.  
  1630.       CurrentInput        =(struct FileHandle*) BADDR(InputFile);
  1631.       MyCommandLine        =    BADDR(CurrentInput->fh_Buf);
  1632.  
  1633.       /* skip ppcdebug`s first string
  1634.        * Small source clipped and changed from
  1635.        * Stevek`s SAS compiler source:-)
  1636.        */
  1637.  
  1638.       line        =    MyCommandLine;
  1639.       while (isspace(*line))
  1640.       {
  1641.         line++;
  1642.       }
  1643.       MyCommandName    =    line;
  1644.       if (*line == QUOTE)
  1645.       {
  1646.         line++;  /* ptr inside quoted string */
  1647.         while (*line != QUOTE && *line != 0)
  1648.         {
  1649.           line++;
  1650.         }
  1651.         if (*line)
  1652.         {
  1653.           *line++    =    '\0';
  1654.         }
  1655.       }
  1656.       else            /* non-quoted arg */
  1657.       {       
  1658.         while ((*line != '\0') && (!isspace(*line)))
  1659.         {
  1660.           line++;
  1661.         }
  1662.         if (*line != '\0')
  1663.         {
  1664.           *line++    =    '\0';
  1665.         }
  1666.       }
  1667.       MyCommandLen    =    strlen(MyCommandName);
  1668.       MyCommandLine    =    line;
  1669.  
  1670.       if (MyObject=PPCLoadObject(MyCommandName))
  1671.       {
  1672.  
  1673.         MyTags[0].ti_Tag    =    NP_Entry;
  1674.         MyTags[0].ti_Data    =(ULONG) &MsgTask;
  1675.         MyTags[1].ti_Tag    =    NP_Name;
  1676.         MyTags[1].ti_Data    =(ULONG) "PPCDebug: MsgTask";
  1677.         MyTags[2].ti_Tag    =    TAG_END;
  1678.  
  1679.         if (MsgProcess=CreateNewProc(&MyTags[0]))
  1680.         {
  1681.           NewCurrentDir    =    NULL;
  1682.           OldCurrentDir    =    NULL;
  1683.           Result    =    ERROR_NO_FREE_STORE;
  1684.  
  1685.  
  1686.           if (MyTaskName=(char*) PPCAllocVec(MyCommandLen + 2,
  1687.                                              MEMF_PUBLIC))
  1688.           {
  1689.             strcpy(MyTaskName,
  1690.                    MyCommandName);
  1691.   
  1692.             MyStackSize            =    My68kStackSize    =    MyCLI->cli_DefaultStack * sizeof(ULONG);
  1693.             if (MyStackSize < DEFAULTPPCSTACK)
  1694.             {
  1695.               MyStackSize = DEFAULTPPCSTACK;
  1696.             }
  1697.             /* strip off the /n the end */
  1698.             MyCommandLinelength        =    strlen(MyCommandLine);
  1699.             p                =    MyCommandLine + MyCommandLinelength;
  1700.             p--;
  1701.             if (*p == '\n')
  1702.             {
  1703.               *p = 0;
  1704.             }
  1705.  
  1706.             if (MyArgument=(char*) PPCAllocVec(MyCommandLinelength + (MyCommandName ? MyCommandLen + 6 : 0),
  1707.                                                MEMF_PUBLIC))
  1708.             {
  1709.               if (MyCommandName)
  1710.               {
  1711.                 MyArgument[0]            =    '"';
  1712.                 memcpy(&MyArgument[1],
  1713.                        &MyCommandName[1],
  1714.                        MyCommandLen);
  1715.                 MyArgument[1+MyCommandLen]    =    '"';
  1716.                 MyArgument[1+1+MyCommandLen]    =    ' ';
  1717.                 Index                =    1+1+1+MyCommandLen;
  1718.               }
  1719.               else
  1720.               {
  1721.                 Index                =    0;
  1722.               }
  1723.               memcpy(&MyArgument[Index],
  1724.                      MyCommandLine,
  1725.                      MyCommandLinelength);
  1726.     
  1727.               if (rdargs_line=PPCAllocVec(MyCommandLinelength + 2, MEMF_ANY))
  1728.               {
  1729.                 memcpy(rdargs_line,
  1730.                        MyCommandLine,
  1731.                        MyCommandLinelength);
  1732.                 rdargs_line[MyCommandLinelength]    =    '\n';
  1733.                 rdargs_line[MyCommandLinelength+1]    =    '\0';
  1734.  
  1735.                 if (M68kPort=PPCCreatePortTags(TAG_END))
  1736.                 {
  1737.                   if (MyStartupMsg=PPCCreateMessage(M68kPort,sizeof(struct StartupData)))
  1738.                   {
  1739.                     if (MyStartupData=(struct StartupData*)
  1740.                                       PPCAllocVec(sizeof(struct StartupData),MEMF_CLEAR|MEMF_PUBLIC))
  1741.                     {
  1742.                       MyStartupData->M68kPort    =    M68kPort;
  1743.                       MyStartupData->std_in    =    Input();
  1744.                       MyStartupData->std_out    =    Output();
  1745.                       MyStartupData->std_err    =    MyProcess->pr_CES;
  1746.                       MyStartupData->Flags    =    STARTUPF_ELFLOADSEG;
  1747.  
  1748.                       CurrentInput        =(struct FileHandle*) BADDR(MyStartupData->std_in);
  1749.                       CurrentInputBPTR        =    MyStartupData->std_in;
  1750.                       OldBuffer            =    CurrentInput->fh_Buf;
  1751.                       OldPosition        =    CurrentInput->fh_Pos;
  1752.                       OldEnd            =    CurrentInput->fh_End;
  1753.  
  1754.  
  1755.  
  1756.                       MyInfo.Address        =    NULL;
  1757.                       MyInfo.Name        =    "_ixbaseobj";
  1758.                       MyInfoTags[0].ti_Tag    =    TAG_END;
  1759.  
  1760.                       if (PPCGetObjectAttrs(MyObject,
  1761.                                             &MyInfo,
  1762.                                             MyInfoTags))
  1763.                       {
  1764.                         CTRL_C_CHECK        =    FALSE;
  1765.                       }
  1766.                       else
  1767.                       {
  1768.                         CTRL_C_CHECK        =    TRUE;
  1769.                       }
  1770.  
  1771.                       MyHook.h_Entry        =    (ULONG (*)(void)) ExceptionHookFunc;
  1772.                       MyHook.h_SubEntry        =    (ULONG (*)(void)) NULL;
  1773.                       MyHook.h_Data        =    (APTR) PPCLibBase;
  1774.  
  1775.                       MyTags[0].ti_Tag        =    PPCTASKTAG_STOPTASK;
  1776.                       MyTags[0].ti_Data        =    TRUE;
  1777.                       MyTags[1].ti_Tag        =    PPCTASKTAG_WAITFINISH;
  1778.                       MyTags[1].ti_Data        =    TRUE;
  1779.                       MyTags[2].ti_Tag        =    PPCTASKTAG_INPUTHANDLE;
  1780.                       MyTags[2].ti_Data        =    (ULONG) MyStartupData->std_in;
  1781.                       MyTags[3].ti_Tag        =    PPCTASKTAG_OUTPUTHANDLE;
  1782.                       MyTags[3].ti_Data        =    (ULONG) MyStartupData->std_out;
  1783.                       MyTags[4].ti_Tag        =    PPCTASKTAG_ARG1;
  1784.                       MyTags[4].ti_Data        =    (ULONG) MyArgument;
  1785.                       MyTags[5].ti_Tag        =    PPCTASKTAG_STACKSIZE;
  1786.                       MyTags[5].ti_Data        =    MyStackSize;
  1787.                       MyTags[6].ti_Tag        =    NP_CloseInput;
  1788.                       MyTags[6].ti_Data        =    FALSE;
  1789.                       MyTags[7].ti_Tag        =    NP_CloseOutput;
  1790.                       MyTags[7].ti_Data        =    FALSE;
  1791.                       MyTags[8].ti_Tag        =    NP_Cli;
  1792.                       MyTags[8].ti_Data        =    TRUE;
  1793.                       MyTags[9].ti_Tag        =    PPCTASKTAG_BREAKSIGNAL;
  1794.                       MyTags[9].ti_Data        =    CTRL_C_CHECK;
  1795.                       MyTags[10].ti_Tag        =    NP_Arguments;
  1796.                       MyTags[10].ti_Data    =    (ULONG)rdargs_line;
  1797.                       MyTags[11].ti_Tag        =    NP_Name;
  1798.                       MyTags[11].ti_Data    =    (ULONG) MyTaskName,
  1799.                       MyTags[12].ti_Tag        =    NP_CommandName;
  1800.                       MyTags[12].ti_Data    =    (ULONG) MyTaskName,
  1801.                       MyTags[13].ti_Tag        =    PPCTASKTAG_STARTUP_MSG;
  1802.                       MyTags[13].ti_Data    =(ULONG)MyStartupMsg;
  1803.                       MyTags[14].ti_Tag        =    PPCTASKTAG_STARTUP_MSGDATA;
  1804.                       MyTags[14].ti_Data    =(ULONG)MyStartupData;
  1805.                       MyTags[15].ti_Tag        =    PPCTASKTAG_STARTUP_MSGLENGTH;
  1806.                       MyTags[15].ti_Data    =    sizeof(struct StartupData);
  1807.                       MyTags[16].ti_Tag        =    PPCTASKTAG_STARTUP_MSGID;
  1808.                       MyTags[16].ti_Data    =    MSGID_EXIT;
  1809.                       MyTags[17].ti_Tag        =    NP_StackSize;
  1810.                       MyTags[17].ti_Data    =    My68kStackSize;
  1811.                       MyTags[18].ti_Tag        =    PPCTASKTAG_EXCEPTIONHOOK;
  1812.                       MyTags[18].ti_Data    =    (ULONG) &MyHook;
  1813.  
  1814.                       MyTags[19].ti_Tag        =    TAG_END;
  1815.  
  1816.                       Result=(ULONG) PPCCreateTask(MyObject,
  1817.                                                    &MyTags[0]);
  1818.  
  1819.                       /* The startupmsg MUST be replied when PPCCreateTask
  1820.                        * returns so this is safe.
  1821.                        * Trust me...:-)
  1822.                        */
  1823.                       while (PPCGetMessage(M68kPort));
  1824.  
  1825.                       UnGetC(CurrentInputBPTR,-1);
  1826.                       CurrentInput->fh_Buf    =    OldBuffer;
  1827.                       CurrentInput->fh_Pos    =    OldPosition;
  1828.                       if (CurrentInput->fh_End)
  1829.                       {
  1830.                         CurrentInput->fh_End    =    OldEnd;
  1831.                       }
  1832.                       PPCFreeVec(MyStartupData);
  1833.                     }
  1834.                     PPCDeleteMessage(MyStartupMsg);
  1835.                   }
  1836.                   PPCDeletePort(M68kPort);
  1837.                 }
  1838.                 PPCFreeVec(rdargs_line);
  1839.               }
  1840.               PPCFreeVec(MyArgument);
  1841.             }
  1842.             PPCFreeVec(MyTaskName);
  1843.           }
  1844.  
  1845.  
  1846.           printf("Result:0x%lx\n",Result);
  1847.           if (MsgProcess)
  1848.           {
  1849.             Signal(&MsgProcess->pr_Task,
  1850.                    1<<SIGBREAKB_CTRL_C);
  1851.             while (MsgProcess);
  1852.           }
  1853.         }
  1854.         else
  1855.         {
  1856.           Printf("Can't create debugger msg task\n");
  1857.         }
  1858.         PPCUnLoadObject(MyObject);
  1859.       }
  1860.       else
  1861.       {
  1862.         Printf("Can't load %s\n",
  1863.                MyCommandName);
  1864.       }
  1865.       CloseLibrary(PPCDissBase);
  1866.     }
  1867.     else
  1868.     {
  1869.       Printf("Can't open ppcdiss.library\n");
  1870.     }
  1871.     CloseLibrary(PPCLibBase);
  1872.   }
  1873. }
  1874.